Android Camera2 使用总结
本文作者
作者:_小河马
链接:http://www.jianshu.com/p/73fed068a795
本文由作者投稿。
最近在做自定义相机相关的项目,网上查了资料都是有关android.hardware.Camera的资料,开始使用的才发现这个类已经废弃了。
Android 5.0(21)之后android.hardware.Camera就被废弃了,取而代之的是全新的android.hardware.Camera2 。
Android 5.0对拍照API进行了全新的设计,新增了全新设计的Camera v2 API,这些API不仅大幅提高了Android系统拍照的功能,还能支持RAW照片输出,甚至允许程序调整相机的对焦模式、曝光模式、快门等。
demo 地址
https://github.com/Hemumu/WallpaperDemo
Camera2主要的类说明
CameraManager:摄像头管理器。这是一个全新的系统管理器,专门用于检测系统摄像头、打开系统摄像头。除此之外,调用CameraManager的getCameraCharacteristics(String)方法即可获取指定摄像头的相关特性。
CameraCharacteristics:摄像头特性。该对象通过CameraManager来获取,用于描述特定摄像头所支持的各种特性。
CameraDevice:代表系统摄像头。该类的功能类似于早期的Camera类。
CameraCaptureSession:这是一个非常重要的API,当程序需要预览、拍照时,都需要先通过该类的实例创建Session。而且不管预览还是拍照,也都是由该对象的方法进行控制的,其中控制预览的方法为setRepeatingRequest();控制拍照的方法为capture()。
CameraRequest和CameraRequest.Builder:当程序调用setRepeatingRequest()方法进行预览时,或调用capture()方法进行拍照时,都需要传入CameraRequest参数。CameraRequest代表了一次捕获请求,用于描述捕获图片的各种参数设置,比如对焦模式、曝光模式……总之,程序需要对照片所做的各种控制,都通过CameraRequest参数进行设置。CameraRequest.Builder则负责生成CameraRequest对象。
开启相机请一定添加相关的相机权限,判断6.0以后添加动态权限的获取。如果相机预览出现黑屏多半就是因为没有相机权限而导致的
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
首页我们要设置相机相关的参数
通过getSystemService(Context.CAMERA_SERVICE);拿到了CameraManager 返回当前可用的相机列表,在这里你可以选择使用前置还是后置摄像头。
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);可以拿到当前相机的相关参数,在这里你可以进行相关的参数检查,例如检查闪光灯是否支持等。在这里我们拿到当前相机的cameraId后面使用。
拿到cameraId我们就可以调用CameraManager的openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)打开相机了
添加 CameraDevice.StateCallback 监听
我们需要对相机状态就行监听,以便在相机状态发生改变的时候做相应的操作。openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)中CameraDevice.StateCallback就是对相机的状态改变的Callback
创建 CameraCaptureSession
在onOpened()中我们可以拿到CameraDevice对象,在相机打开后需要创建CameraCaptureSession。
CameraCaptureSession是什么呢?由于Camera2是一套全新的API,所以它引用了管道的概念将安卓设备和摄像头之间联通起来,系统向摄像头发送 Capture 请求,而摄像头会返回 CameraMetadata。这一切建立在一个叫作 CameraCaptureSession的会话中。如下图:
图片来自http://wiki.jikexueyuan.com/project/android-actual-combat-skills/android-hardware-camera2-operating-guide.html
这里我们需要预览相机的内容就需要创建CameraCaptureSession向相机发送Capture请求预览相机内容
首先我们创建了一个CaptureRequest 上面说过了我们需要跟相机通信只有通过CameraCaptureSession。而要和CameraCaptureSession通信就是发送请求。这里我们相当于在创建请求的一些参数。
createCaptureRequest(int); 也有很多参数可选。
这里我们发送的是CameraDevice.TEMPLATE_PREVIEW也就是告诉相机我们只需要预览。更多参数如下:
TEMPLATE_RECORD 创建适合录像的请求。
TEMPLATE_PREVIEW 创建一个适合于相机预览窗口的请求。
TEMPLATE_STILL_CAPTURE 创建适用于静态图像捕获的请求
TEMPLATE_VIDEO_SNAPSHOT 在录制视频时创建适合静态图像捕获的请求。
详细信息可以参考官网的API文档。
调用创建方法createCaptureSession(List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler) 第一参数就是我们需要输出到的Surface列表,这里我们可以输出到一个SurfaceView中或者TextureView中。
第二参数是对创建过程的一个回调方法,当onConfigured回调的时候说明CameraCaptureSession创建成功了。
现在我们可以向CameraCaptureSession发送前面创建的好的预览相机请求了。调用mCaptureSession.setRepeatingRequest(mPreviewRequest,null, mBackgroundHandler); 这样我们就开启的相机的预览,在刚才添加的输出Surface对应的控件中我们可以看到摄像头的预览内容了。
当我们需要拍照并且得到相应的照片数据的时候和开启相机预览相同的操作,我们只需要向CameraCaptureSession发送我们创建好的请求就行,就像我们请求网络数据一样,封装好参数直接告诉CameraCaptureSession需要做什么由它去和相机建立通信并执行相应的操作。
对焦
向CameraCaptureSession发送对焦请求,并且对对焦是否成功进行监听,在mCaptureCallback中对回调进行处理
拍摄图片
对焦完成后我们就可以向CameraCaptureSession发送请求可以拍照了
相信看到这里代码已经不复杂了,组装好我们的请求然后用CameraCaptureSession发送这个请求就可以了。
这里需要注意的是我们怎么拿到图片数据呢? 这里要说回在创建CameraCaptureSession时参数不是有一个输出的Surface列表么,在列表中添加一个ImageReader的Surface用户获取图片数据
mCameraDevice
.createCaptureSession(
Arrays.asList(surface, mImageReader.getSurface()),null).....
在ImageReader中对图片获取就行监听
调用reader.acquireNextImage()我们就可以拿到当前的图片数据了。拍完后我们需要解锁焦点让相机回到预览状态,同样的我们发送请求就可以了
效果
之前看了鸿神推送的Android 仿火萤视频桌面 神奇的LiveWallPaper 一文中提到了用相机来做壁纸也就是透明屏幕,项目地址https://github.com/songixan/Wallpaper 查看源码发现还是用的旧的CameraAPI,所以我在Demo中用Camera2API做了透明屏幕,有兴趣的可以去看下。
PS:后来在同事的小米2S(5.1.1)中测试发现出错了,初步猜测是分辨率的原因,目前正在解决中。有问题大家可以私信我 谢谢~
到此Camera2的学习就结束了,同样的如果你想用相机就行拍摄视频也是如此,用CameraCaptureSession发送相应的请求了就可以了,大家有兴趣可以做一做视频的拍摄。现在做微信的小10秒小视频拍摄也很简单了,思路很简单当用户按下拍摄按钮用CameraCaptureSession发送拍摄视频的请求,松开手指的时候相机恢复到预览状态。so easy~ 大家有兴趣可以尝试下。
拍摄视频的Demo
https://github.com/googlesamples/android-Camera2Video
Tinks android.hardware.camera2 使用指南
http://wiki.jikexueyuan.com/project/android-actual-combat-skills/android-hardware-camera2-operating-guide.html
如果你有想学习的文章直接留言,我会整理征稿。如果你有好的文章想和大家分享欢迎投稿,直接向我投递文章链接即可。
欢迎长按下图->识别图中二维码或者扫一扫关注我的公众号: